package com.common.util;

import cn.hutool.core.util.StrUtil;
import org.springframework.web.multipart.MultipartFile;
import sun.misc.BASE64Encoder;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.*;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;

/**
 * 文件上传、下载工具类
 */
public class UpDownUtil {

    /**
     * 保存文件，直接以multipartFile形式
     * @param multipartFile
     * @param path 文件保存绝对路径
     * @return 返回文件名
     * @throws IOException
     */
    public static String saveFile(MultipartFile multipartFile, String path,String fileName) throws IOException {
        File file = new File(path);
        if (!file.exists()) {
            file.mkdirs();
        }
        InputStream inputStream = multipartFile.getInputStream();
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(path + File.separator + fileName));
        byte[] bs = new byte[1024];
        int len;
        while ((len = inputStream.read(bs)) != -1) {
            bos.write(bs, 0, len);
        }
        bos.flush();
        bos.close();
        return fileName;
    }

    /**
     * 文件下载
     */
    public static String download(File file, HttpServletResponse response) throws IOException {
        if (!file.exists()) {
            return "下载失败，附件不存在";
        }
        String fileName = file.getName();
        System.out.println("path = "+file.getAbsolutePath());
        InputStream inStream = new FileInputStream(file);
        return download(inStream, fileName, response);
    }

    /**
     * 文件下载
     */
    public static String download(InputStream inStream,String fileName, HttpServletResponse response) throws IOException {
        String msg = "";
        response.setContentType("text/html; charset=UTF-8"); //设置编码字符
        response.setContentType("application/octet-stream"); //设置内容类型为下载类型
        //这里注意 一定要在response.getOutputStream()之前就把这个setHeader属性设进去，否则也不生效
        response.setHeader("Content-Length", String.valueOf(inStream.available()));
        response.setHeader("Content-Disposition","attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
        response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
        try {
            OutputStream os = response.getOutputStream();
            byte[] buff = new byte[1024];
            int len = -1;
            while ((len = inStream.read(buff)) > 0) {
                os.write(buff, 0, len);
            }
            msg="下载成功";
            os.flush();
            os.close();
            inStream.close();
        }catch (IOException e){
            msg="下载失败，系统找不到指定路径";
        }
        return msg;
    }

    /**
     * 将图片内容转换成Base64编码的字符串
     * @param path 图片文件的全路径名称
     * @return base64字符串和图片宽高
     */
    public static Map<String,String> getImageBase64String(String path) {
        Map<String,String> map = new HashMap<>();
        if (StrUtil.isEmpty(path)) return null;

        File file = new File(path);
        if (!file.exists()) return null;

        InputStream is = null;
        InputStream is1 = null;
        byte[] data = null;
        try {
            is = new FileInputStream(file);
            is1 = new FileInputStream(file);
            data = new byte[is.available()];
            is.read(data);
            //获取图片宽高
            BufferedImage image = ImageIO.read(is1);
            //图片的原始宽高
            map.put("height",Integer.toString(image.getHeight()));
            map.put("width",Integer.toString(image.getWidth()));
            is.close();
            is1.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        BASE64Encoder encoder = new BASE64Encoder();
        map.put("encode",encoder.encode(data));
        return map;
    }

    /**
     * 将图片内容转换成Base64编码的字符串，并获得图片宽高，进行缩放
     * @param path 图片文件的全路径名称
     * @param flag 判断图片是否是用户头像
     * @return base64字符串和图片宽高
     */
    public static Map<String,String> getImageBase64String(String path,boolean flag) {
        Map<String,String> map = new HashMap<>();
        if (StrUtil.isEmpty(path)) return null;

        File file = new File(path);
        if (!file.exists()) return null;

        InputStream is = null;
        InputStream is1 = null;
        byte[] data = null;
        try {
            is = new FileInputStream(file);
            is1 = new FileInputStream(file);
            data = new byte[is.available()];
            is.read(data);
            //获取图片宽高
            BufferedImage image = ImageIO.read(is1);
            //图片的原始宽高
            int height = image.getHeight();
            int width  = image.getWidth();
            //如果图片是用户头像的话，按照50*50的标准来判断是否要缩小，否则的话按照500*500
            if (flag){
                //宽或高有一项大于50时，等比缩小
                if (width > 50 || height > 50){
                    int cWidth  = 50;
                    int cHeight  = 50;
                    int showWidth = cWidth;
                    int showHeight = cHeight;
                    //原图宽高太大进行等比缩放
                    if(1.0 * width/height >= 1.0 * cWidth/cHeight){
                        //图片比较宽
                        showHeight = showWidth * height / width;
                    }else {
                        //图片比较长
                        showWidth = showHeight * width / height;
                    }
                    map.put("height",Integer.toString(showHeight));
                    map.put("width",Integer.toString(showWidth));
                }else {
                    //否则使用图片的原始大小
                    map.put("height",Integer.toString(height));
                    map.put("width",Integer.toString(width));
                }
            }else {
                //宽或高大于500时，进行缩放
                if (width > 500 || height > 500){
                    int cWidth  = 500;
                    int cHeight  = 500;
                    int showWidth = cWidth;
                    int showHeight = cHeight;
                    //原图宽高太大进行等比缩放
                    if(1.0 * width/height >= 1.0 * cWidth/cHeight){
                        //图片比较宽
                        showHeight = showWidth * height / width;
                    }else {
                        //图片比较长
                        showWidth = showHeight * width / height;
                    }
                    map.put("height",Integer.toString(showHeight));
                    map.put("width",Integer.toString(showWidth));
                }else {
                    map.put("height",Integer.toString(height));
                    map.put("width",Integer.toString(width));
                }
            }
            is.close();
            is1.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        BASE64Encoder encoder = new BASE64Encoder();
        map.put("encode",encoder.encode(data));
        return map;
    }
}
